{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "start\n",
      "epoch: 0 accuracy: 0.0955555555556\n",
      "epoch: 1000 accuracy: 0.633333333333\n",
      "epoch: 2000 accuracy: 0.902222222222\n",
      "epoch: 3000 accuracy: 0.913333333333\n",
      "epoch: 4000 accuracy: 0.924444444444\n",
      "epoch: 5000 accuracy: 0.928888888889\n",
      "epoch: 6000 accuracy: 0.944444444444\n",
      "epoch: 7000 accuracy: 0.948888888889\n",
      "epoch: 8000 accuracy: 0.942222222222\n",
      "epoch: 9000 accuracy: 0.948888888889\n",
      "epoch: 10000 accuracy: 0.948888888889\n",
      "epoch: 11000 accuracy: 0.953333333333\n",
      "epoch: 12000 accuracy: 0.955555555556\n",
      "epoch: 13000 accuracy: 0.957777777778\n",
      "epoch: 14000 accuracy: 0.962222222222\n",
      "epoch: 15000 accuracy: 0.957777777778\n",
      "epoch: 16000 accuracy: 0.96\n",
      "epoch: 17000 accuracy: 0.944444444444\n",
      "epoch: 18000 accuracy: 0.962222222222\n",
      "epoch: 19000 accuracy: 0.96\n",
      "epoch: 20000 accuracy: 0.964444444444\n",
      "end\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "from sklearn.datasets import load_digits\n",
    "from sklearn.preprocessing import LabelBinarizer\n",
    "from sklearn.cross_validation import train_test_split\n",
    "\n",
    "def sigmoid(x):\n",
    "    return 1/(1+np.exp(-x))\n",
    "\n",
    "def dsigmoid(x):\n",
    "    return x*(1-x)\n",
    "\n",
    "class NeuralNetwork:\n",
    "    def __init__(self,layers):#(64,100,10)\n",
    "        #权值的初始化，范围-1到1\n",
    "        self.V = np.random.random((layers[0]+1,layers[1]+1))*2-1\n",
    "        self.W = np.random.random((layers[1]+1,layers[2]))*2-1\n",
    "        \n",
    "    def train(self,X,y,lr=0.11,epochs=10000):\n",
    "        #添加偏置\n",
    "        temp = np.ones([X.shape[0],X.shape[1]+1])\n",
    "        temp[:,0:-1] = X\n",
    "        X = temp\n",
    "        \n",
    "        for n in range(epochs+1):\n",
    "            i = np.random.randint(X.shape[0]) #随机选取一个数据\n",
    "            x = [X[i]]\n",
    "            x = np.atleast_2d(x)#转为2维数据\n",
    "            \n",
    "            L1 = sigmoid(np.dot(x,self.V))#隐层输出\n",
    "            L2 = sigmoid(np.dot(L1,self.W))#输出层输出\n",
    "            \n",
    "            L2_delta = (y[i]-L2)*dsigmoid(L2)\n",
    "            L1_delta= L2_delta.dot(self.W.T)*dsigmoid(L1)\n",
    "            \n",
    "            self.W += lr*L1.T.dot(L2_delta)\n",
    "            self.V += lr*x.T.dot(L1_delta)\n",
    "            \n",
    "            #每训练1000次预测一次准确率\n",
    "            if n%1000==0:\n",
    "                predictions = []\n",
    "                for j in range(X_test.shape[0]):\n",
    "                    o = self.predict(X_test[j])\n",
    "                    predictions.append(np.argmax(o))#获取预测结果\n",
    "                accuracy = np.mean(np.equal(predictions,y_test))\n",
    "                print('epoch:',n,'accuracy:',accuracy)\n",
    "        \n",
    "    def predict(self,x):\n",
    "        #添加偏置\n",
    "        temp = np.ones(x.shape[0]+1)\n",
    "        temp[0:-1] = x\n",
    "        x = temp\n",
    "        x = np.atleast_2d(x)#转为2维数据\n",
    "\n",
    "        L1 = sigmoid(np.dot(x,self.V))#隐层输出\n",
    "        L2 = sigmoid(np.dot(L1,self.W))#输出层输出\n",
    "        return L2\n",
    "\n",
    "digits = load_digits()#载入数据\n",
    "X = digits.data#数据\n",
    "y = digits.target#标签\n",
    "#输入数据归一化\n",
    "X -= X.min()\n",
    "X /= X.max()\n",
    "\n",
    "nm = NeuralNetwork([64,100,10])#创建网络\n",
    "\n",
    "X_train,X_test,y_train,y_test = train_test_split(X,y) #分割数据1/4为测试数据，3/4为训练数据\n",
    "\n",
    "labels_train = LabelBinarizer().fit_transform(y_train)#标签二值化     0,8,6   0->1000000000  3->0001000000\n",
    "labels_test = LabelBinarizer().fit_transform(y_test)#标签二值化\n",
    "\n",
    "print('start')\n",
    "\n",
    "nm.train(X_train,labels_train,epochs=20000)\n",
    "\n",
    "print('end')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python [default]",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
